package com.ftg.learn.framework.mybatis.javabase.util;

import com.ftg.learn.framework.mybatis.javabase.mapper.StudentMapper;
import com.mysql.cj.jdbc.MysqlDataSource;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

import javax.sql.DataSource;
import javax.xml.transform.Source;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Properties;

/**
 * 通用的功能设计封装
 * <p>
 * 对mybatis通用部分进行面向对象的封装
 *
 * @author kangjx
 * @version 1.0
 * @date 2023/9/4 上午8:44
 */
public class MybatisUtil {

    private final String url = "jdbc:mysql://localhost:3309/j2305?timeZone=Asia/Harbin&characterEncoding=utf-8";
    private final String user = "root";
    private final String password = "123456";

    /**
     * 想使用mybatis 一定要有四大基础信息
     * 1 驱动类
     * 2 mybatis 包
     * 3 : mysql 四大基础信息
     * 3.1 乱码  时区的问题
     * 4 : 想办法  3--> sqlSessionFactoryBuilder -->  sqlSessionFactory -->   sqlSession  --> getMapper(） --> 接口代理 ->> 调用里面的方法
     */

    /**
     * 用来生成数据源
     *
     * @param url      连接串
     *                 ex jdbc:mysql://localhost:3309/exercise01?timeZone=Asia/Harbin&characterEncoding=utf-8
     * @param user     用户名
     * @param password 密码
     * @return
     */
    private DataSource createDataSource(String url, String user, String password) {
        MysqlDataSource dataSource = new MysqlDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setURL(url);
        return dataSource;
    }

    private DataSource createDataSource() {

        Properties p = new Properties();
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader("com/ftg/learn/framework/mybatis/javabase/config/jdbc.properties");
            p.load(reader);
        } catch (IOException e) {
            System.err.println("是你的文件地址有误!!");
        }

        MysqlDataSource dataSource = new MysqlDataSource();
        String mode = p.getProperty("active.mode");
        dataSource.setUser(p.getProperty(mode + ".mysql.user"));
        dataSource.setPassword(p.getProperty(mode + ".mysql.password"));
        dataSource.setURL(p.getProperty(mode + ".mysql.url"));
        return dataSource;
    }

    /**
     * 为我们产生了一个环境类吧
     *
     * @return
     */
    private Environment initEnv() {
        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        Environment e = new Environment("kjxlocalmysql", transactionFactory, this.createDataSource());
        return e;
    }

    private Configuration initConfiguration() {
        Configuration configuration = new Configuration();

        //setting
        configuration.setCacheEnabled(true);
        //打开sql打印功能  开发阶段
        configuration.setLogImpl(StdOutImpl.class);

        //把环境给配置
        configuration.setEnvironment(this.initEnv());

        //没有mybatis缓存当中找到  showListWithParameter 的映射 mapper 就叫映射 sql

        //sql 接口里注解 还有一个就是xml 。就是没有直接找到把一个.xml注入mapper缓存的方法

        // 读取 Student.xml 映射文件
        String resource = "com/ftg/learn/framework/mybatis/javabase/mapper/xml/student.xml"; // 替换为你的映射文件路径
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(resource);


        // 使用 XMLMapperBuilder 注入映射文件
        XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(inputStream, configuration, resource, null);
        xmlMapperBuilder.parse();

        return configuration;
    }

    public SqlSession getSqlSession() {

        //工厂建造的实例化
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 实例化工厂
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(this.initConfiguration());

        return sqlSessionFactory.openSession();
    }


    public void commit(SqlSession session) {
        session.commit();
    }

    public void rollback(SqlSession session) {
        session.rollback();
    }

    public void close(SqlSession session) {
        session.close();
    }

}
